Most hardware and operating systems support multiple memory page sizes. For example, the POWER4 architecture offers two page sizes: 4 Kilobyte pages (small pages) and 16 Megabyte pages (large pages), which are supported by AIX and Linux. The performance benefits of using large page sizes include reduced Translation Lookaside Buffer (TLB) misses and reduced page faults. On some computer architectures large pages may improve hardware prefetching if the prefetching mechanism extends to the large page scope. Large pages also provide a contiguous data layout in real memory which may benefit cache behavior and prefetching. However, the use of larger page sizes comes at a cost. There is an increase in fragmentation and an increase in memory footprint that may cause additional paging overhead in the operating system, especially in a multi-programmed environment. Further, large pages are typically pinned reducing the amount of pageable memory in the system.
Moreover, current interfaces in commercial operating systems and hardware have placed the burden on the end user to make the decision of which data objects in an application's data space to map to large pages, thus further limiting large page usability. For example, on the AIX operating system, memory has to be first partitioned into pools: a small- and large-page pool. The size of each pool must be determined by the user prior to running an application. End users can set a system environment variable or mark the application binary to indicate that they want to use large pages with an application. If large page usage is indicated, the entire data space (i.e., the static data and dynamic heap allocated data segments) is backed by large pages. Given these constraints, the decision of which portions of the application data space should be mapped to different page sizes is non-trivial.
An alternative, more selective, method to request large page memory on AIX is provided through allocating shared memory using the shmget system call with the large page flag enabled. The drawback of the first approach (environment variable and binary marking) is that it is an “all-or-nothing” approach; the entire data footprint must be backed by large pages. An all-or-nothing strategy is undesirable if only a small number of large pages is available, or in multi-programmed environments, where multiple applications are competing for the available large pages. The second shared memory strategy offers the ability to use large pages for only selected portions of the data space, thus allowing an application to be executed with reduced large page resources. However, the burden is on the programmer to identify the appropriate portions, which requires in-depth knowledge of the application's behavior and its data structures. To date, no reliable guideline exists for when to use large pages or which portions of the data space would benefit most from large pages. Due to these usage challenges, large pages, in spite of their potentially significant performance benefits, often remain unexploited in today's commercial systems.
There has been work at the operating system level on automatically using large pages. Romer et al. states that “good policies for superpages have been elusive because a cost benefit analysis is required to determine if the overhead of constructing a superpage is outweighed by its benefit”. Their work, as well as more recent work, automatically migrate data from small pages to large pages reactively with analysis performed at the operating system level using data gathered by the system. The operating system, however, does not have enough knowledge of an application's data structures to selectively partition the application's data space. Furthermore, the system is only aware of the order that memory allocation requests are made and must make a decision based on that, while a higher-level mechanism can implement a predictive approach.
There has also been an exploratory approach to finding the best page size for more application data. This approach transparently explores all different page size options at runtime and then selects the best performing option as the final page size. This approach assumes that the entire data space of an application is moved to a different page size and does not address a hybrid page size allocation where the data space is partitioned into multiple sections of different page sizes.
Therefore, there is a need for a method and system that address the problem of working within a fixed budget of large pages or to determine the most beneficial subset of an application's data space to back with the available large pages.